﻿
using System;
using System.Collections;
using System.Configuration;
using System.Data;

using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using System.Data.Odbc;
using System.Data.OleDb;
using System.IO;
using HZ.DrugTrade.Model;
using HZ.DrugTrade.IBLL;
using HZ.DrugTrade.BLLFactory;
using System.Collections.Generic;
using System.Text;
using HZ.DrugTrade.Model.Enum;

namespace HZ.DrugTrade.Web.Hospitals.Procurement
{
    public partial class PurchaseOrderImport : BasePage
    {
        IBLL_ProcurementBasic ipb = Factory.BLL_ProcurementBasic();
        IBLL_Purchase purchaseCtrl = Factory.BLL_Purchase();

        protected void Page_Load(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// 上传文件，字段对应准备
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void StartNextButton_Click(object sender, EventArgs e)
        {
            if (!Page.IsValid)
            {
                //页面输入不合法 取消下一步
                //e.Cancel = true;
                return;
            }
            if (this.FileUpload1.HasFile)
            {
                string strPath = this.Server.MapPath(ConfigurationManager.AppSettings.Get("ImportPath"));
                string strTempFile = strPath + "\\" + Guid.NewGuid().ToString() + Path.GetExtension(this.FileUpload1.PostedFile.FileName);

                //this.hdnTempFile.Value = strTempFile;
                ViewState["TempFile"] = strTempFile;
                ViewState["SheetName"] = this.txtTableName.Text.Trim();
                ViewState["ImportType"] = Request.Form["ImportType"];
                if (DirectoryExist(strPath))
                {

                    try
                    {
                        //保存临时文件
                        this.FileUpload1.SaveAs(strTempFile);

                        //绑定映射关系
                        BindRelation();
                        //
                        //Wizard1.ActiveStepIndex += 1;
                    }
                    catch (Exception ex)
                    {
                        PageError(ex.Message, "");
                        return;
                    }
                }
                else
                {
                    PageError("请确保临时目录有写权限！", "");
                }

            }
            else
            {
                PageError("文件不存在！请重新选择文件。", "");
            }
        }

        /// <summary>
        /// 后退到第一步 选择导入文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void FinishPreviousButton_Click(object sender, EventArgs e)
        {
            //删除临时文件
            string strTempFile = this.hdnTempFile.Value;
            //DeleteTempFile(strTempFile);
            //Wizard1.ActiveStepIndex = 0;

        }

        /// <summary>
        /// 初始化字段映射关系grid 
        /// </summary>
        private void BindRelation()
        {
            //获取临时文件
            string strTempFile = ViewState["TempFile"].ToString();
            string strSheetName = ViewState["SheetName"].ToString();
            string strImportType = ViewState["ImportType"].ToString();

            DataTable tableSrc = GetDataTableFromTempFile(strTempFile, strSheetName, strImportType, false);
            DataTable tableDes = new DataTable();

            if (tableSrc.Rows.Count == 0)
            {
                PageError("没有数据", this.ReturnUrl);
            }

            //给新table添加列
            DataColumn col0 = new DataColumn("标题行", typeof(System.String));

            tableDes.Columns.Add(col0);
            if (tableSrc.Rows.Count > 1)
            {
                DataColumn col1 = new DataColumn("行1", typeof(System.String));
                tableDes.Columns.Add(col1);
            }

            //原表的前两行倒置成新表
            for (int i = 0; i < tableSrc.Columns.Count; i++)
            {
                DataRow row = tableDes.NewRow();
                for (int j = 0; j < tableDes.Columns.Count; j++)
                {
                    row[j] = tableSrc.Rows[j][i];
                }
                tableDes.Rows.Add(row);

            }
            //
            this.rptRelation.DataSource = tableDes;
            this.rptRelation.DataBind();


        }

        /// <summary>
        /// 校验步骤后退
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void StepPreviousButton_Click(object sender, EventArgs e)
        {
            //Wizard1.ActiveStepIndex = 0;
            string strTempFile = ViewState["TempFile"].ToString();
            DeleteTempFile(strTempFile);
        }

        /// <summary>
        /// 数据校验
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void StepNextButton_Click(object sender, EventArgs e)
        {
            int count = 0;
            bool CheckResult = false;
            this.CheckResult.Value = "";
            StringBuilder strDuplicateRecord = new StringBuilder();
            StringBuilder strUnPassRecord = new StringBuilder();
            StringBuilder result = new StringBuilder();
            //获取临时文件名
            string strTempFile = ViewState["TempFile"].ToString();
            string strSheetName = ViewState["SheetName"].ToString();
            string strImportType = ViewState["ImportType"].ToString();
            //哈希表 用于存放对应关系
            Hashtable field2pos = new Hashtable();

            //将映射关系添入哈希表
            foreach (string key in Request.Form.Keys)
            {
                if (Request.Form.Get(key) == "-1")
                {
                    continue;
                }
                if (!key.StartsWith("column"))
                {
                    continue;
                }
                //对应的系统字段
                string field = Request.Form.Get(key);
                //csv文件中列的顺序
                int pos = Convert.ToInt32(key.Substring(6));
                if (field2pos.Contains(field))
                {
                    PageError("重复映射字段", this.ReturnUrl);
                    return;
                }
                //
                field2pos.Add(field, pos);
                
            }

            //获取数据
            DataTable table = GetDataTableFromTempFile(strTempFile, strSheetName, strImportType, true);

            IList<Model.PurchaseOrderDetail> OrderDetailList = new List<Model.PurchaseOrderDetail>();
            int ErrorPurchaseCount = 0;
            //循环插入数据
            foreach (DataRow row in table.Rows)
            {
                PurchaseOrderDetail purchaseOrderDetail = new PurchaseOrderDetail();
                purchaseOrderDetail.ProcureCatalogID = Convert.ToString(row[Convert.ToInt32(field2pos["ProcureCatalogID"])].ToString().Trim());
                purchaseOrderDetail.PurchaseCount = new HZ.Common.ConvertHelper(row[Convert.ToInt32(field2pos["PurchaseCount"])].ToString().Trim()).ToInt32;

                OrderDetailList.Add(purchaseOrderDetail);

                if (!HZ.Fun2.IsInt(row[Convert.ToInt32(field2pos["PurchaseCount"])].ToString().Trim()))
                {
                    ErrorPurchaseCount++;
                }

                count++;
            }
            //将数据存入ViewState 
            ViewState["PurchaseOrderList"] = OrderDetailList;

            result.Append("<li>" + "数据总条数：" + count + "</li>");

            string hospitalId = CurrentAccount.GetUser().Org.OrgID;
            string procureCatalogIds = StringUtility.GetModelFieldArrayString(OrderDetailList, "ProcureCatalogID", ",", false);
            if (ErrorPurchaseCount == 0)
            {
                //检查有无重复数据
                DataTable duplicateProcureCatalog = purchaseCtrl.GetDuplicateProcureCatalog(procureCatalogIds);
                if (duplicateProcureCatalog.Rows.Count > 0)
                {
                    foreach (DataRow row in duplicateProcureCatalog.Rows)
                    {
                        strDuplicateRecord.Append(row[0].ToString() + ",");
                    }
                    result.Append("<li><font color=red>" + "表格中有重复数据：" + strDuplicateRecord.ToString().TrimEnd(new char[] { ',' }) + "</font></li>");
                }
                else
                {
                    //检查接口数据是否完全对应
                    DataTable UnPassProcureCatalog = purchaseCtrl.GetUnExistInSystemProcureCatalog(hospitalId, procureCatalogIds);
                    if (UnPassProcureCatalog.Rows.Count > 0)
                    {
                        foreach (DataRow row in UnPassProcureCatalog.Rows)
                        {
                            strUnPassRecord.Append(row[0].ToString() + ",");
                        }
                        result.Append("<li><font color=red>" + "表格中不合格的中标序号：" + strUnPassRecord.ToString().TrimEnd(new char[] { ',' }) + "</font></li>");
                    }
                    else
                    {
                        CheckResult = true;
                        result.Append("<li>" + "恭喜！数据完全正确。请输入采购单名称，然后执行导入。" + "</li>");

                    }
                }
            }
            else 
            {
                result.Append("<li><font color=red>" + "表中的采购量有错误！请检查。" + "</font></li>");
            }
            
            ltlResult.Text = result.ToString();

            if (CheckResult)
            {
                tbOrder.Visible = true;
                this.CheckResult.Value = "OK";
                this.txtPurchaseOrderTimeFrom.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                txtPurchaseOrderName.Text = CurrentAccount.GetUser().Org.OrgName + DateTime.Now.ToString("yyyyMMddHHmm") + "采购单";
            }
            
        }

        /// <summary>
        /// 校验完成，执行导入
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Wizard1_FinishButtonClick(object sender, WizardNavigationEventArgs e)
        {
            if (!Page.IsValid)
            {
                //页面输入不合法 取消下一步
                //e.Cancel = true;
                HZ.Web.WebUtil.Alert("页面没有验证成功！请检查数据项是否填写完整。", this);
                return;
            }
            if (this.CheckResult.Value == "OK")
            {

                //添加采购单
                //新采购单信息
                PurchaseOrder aPurchaseOrder = new PurchaseOrder();
                aPurchaseOrder.OrderID = Guid.NewGuid().ToString();
                aPurchaseOrder.HospitalID = CurrentAccount.GetUser().Org.OrgID;
                aPurchaseOrder.OrderName = txtPurchaseOrderName.Text.Trim();
                aPurchaseOrder.StartTime = Convert.ToDateTime(txtPurchaseOrderTimeFrom.Text.Trim());
                aPurchaseOrder.PlanEndTime = Convert.ToDateTime(txtPurchaseOrderTimeTo.Text.Trim());
                aPurchaseOrder.PlanPerson = CurrentAccount.GetUser().UserID;
                aPurchaseOrder.TotalAmount = 0;
                aPurchaseOrder.Remarks = txtRemarks.Text;
                int result = purchaseCtrl.AddPurchaseOrder(aPurchaseOrder);

                if (result == 1)
                {
                    //添加明细
                    IList<Model.PurchaseOrderDetail> OrderDetailList = (IList<Model.PurchaseOrderDetail>)ViewState["PurchaseOrderList"];

                    result = purchaseCtrl.ImportPurchaseOrder(OrderDetailList, aPurchaseOrder);

                    //删除临时文件
                    string strTempFile = ViewState["TempFile"].ToString();
                    DeleteTempFile(strTempFile);
                }
                if (result == 1)
                {
                    PageInfo("恭喜！采购单导入成功。", "PurchaseOrderUnCheck.aspx");
                }
                else
                {
                    PageError("数据导入失败！", "");
                }
            }
            else
            {
                PageError("数据校验失败，无法执行导入！", "");
            }


        }



        #region 功能函数

        /// <summary>
        /// 从指定文件中获取数据集
        /// </summary>
        /// <param name="strPath">文件路径</param>
        /// <param name="strSheetName">数据表名</param>
        /// <param name="strImportType">文件类型</param>
        /// <param name="bhead"></param>
        /// <returns></returns>
        private DataTable GetDataTableFromTempFile(string strPath, string strSheetName, string strImportType, bool bhead)
        {
            string tableName = strSheetName;
            if (strImportType == "excel")
            {
                return ExcelReader(strPath, tableName, bhead);
            }
            else if (strImportType == "access")
            {
                return AccessReader(strPath, tableName, bhead);
            }
            else
            {
                return CsvReader(strPath, bhead);
            }
        }


        /// <summary>
        /// Access文件读取接口
        /// </summary>
        /// <param name="strPath"></param>
        /// <param name="strTableName"></param>
        /// <returns></returns>
        private DataTable AccessReader(string strPath, string strTableName, bool bhead)
        {
            DataSet myDataSet = new DataSet();
            #region#Get Data From CSV As DataSet

            string strConnCSV = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strPath + ";";
            System.Data.OleDb.OleDbConnection objConn = new OleDbConnection(strConnCSV);
            string strSql = "SELECT * FROM [" + strTableName + "]";
            System.Data.OleDb.OleDbDataAdapter odbcCSVDataAdapter = new OleDbDataAdapter(strSql, objConn);
            odbcCSVDataAdapter.Fill(myDataSet);
            if (objConn.State == System.Data.ConnectionState.Open)
            {
                objConn.Close();
            }




            #endregion

            #region #去除空行
            if (myDataSet != null)
            {
                //先如果要取表头 先加表头
                if (bhead)
                {
                    DataTable table = myDataSet.Tables[0];
                    DataRow row = table.NewRow();
                    for (int i = 0; i < table.Columns.Count; i++)
                    {
                        row[i] = table.Columns[i].ColumnName;
                    }
                    table.Rows.InsertAt(row, 0);
                }

                int iColCount = myDataSet.Tables[0].Columns.Count;
                bool delFlg = true;
                for (int i = myDataSet.Tables[0].Rows.Count - 1; i >= 0; i--)
                {
                    DataRow dr = myDataSet.Tables[0].Rows[i];
                    delFlg = true;
                    for (int j = 0; j < iColCount; j++)
                    {
                        if (!Convert.IsDBNull(dr[j]))
                        {
                            delFlg = false;
                            break;
                        }
                    }
                    if (delFlg)
                    {
                        myDataSet.Tables[0].Rows.Remove(dr);
                    }
                }
            }
            #endregion

            return myDataSet.Tables[0];
        }

        /// <summary>
        /// excel文件读取接口
        /// </summary>
        /// <param name="strPath"></param>
        /// <param name="strTableName"></param>
        /// <returns></returns>
        private DataTable ExcelReader(string strPath, string strTableName, bool bhead)
        {
            DataSet myDataSet = new DataSet();
            #region#Get Data From CSV As DataSet

            string strConnCSV = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strPath + ";Extended Properties='Excel 8.0;HDR=" + (bhead ? "Yes" : "No") + ";FMT=Delimited;IMEX=1;'";
            System.Data.OleDb.OleDbConnection objConn = new OleDbConnection(strConnCSV);
            string strSql = "SELECT * FROM [" + strTableName + "$]";
            System.Data.OleDb.OleDbDataAdapter odbcCSVDataAdapter = new OleDbDataAdapter(strSql, objConn);
            odbcCSVDataAdapter.Fill(myDataSet);
            if (objConn.State == System.Data.ConnectionState.Open)
            {
                objConn.Close();
            }

            #endregion

            #region #去除空行
            if (myDataSet != null)
            {
                int iColCount = myDataSet.Tables[0].Columns.Count;
                bool delFlg = true;
                for (int i = myDataSet.Tables[0].Rows.Count - 1; i >= 0; i--)
                {
                    DataRow dr = myDataSet.Tables[0].Rows[i];
                    delFlg = true;
                    for (int j = 0; j < iColCount; j++)
                    {
                        if (!Convert.IsDBNull(dr[j]))
                        {
                            delFlg = false;
                            break;
                        }
                    }
                    if (delFlg)
                    {
                        myDataSet.Tables[0].Rows.Remove(dr);
                    }
                }
            }
            #endregion

            return myDataSet.Tables[0];
        }


        /// <summary>
        /// csv解析成datatble 
        /// </summary>
        /// <param name="sFile"></param>
        /// <param name="bhead"></param>
        /// <returns></returns>
        private DataTable CsvReader(string strFile, bool bhead)
        {
            int intColCount = 0;
            bool blnFlag = true;
            DataTable mydt = new DataTable("table");

            DataColumn mydc;
            DataRow mydr;

            string strline;
            string[] aryline;

            using (System.IO.StreamReader mysr = new System.IO.StreamReader(strFile, Encoding.Default))
            {
                while ((strline = mysr.ReadLine()) != null)
                {
                    aryline = GetCSVLine(strline);

                    if (blnFlag)
                    {
                        blnFlag = false;
                        intColCount = aryline.Length;
                        for (int i = 0; i < aryline.Length; i++)
                        {
                            mydc = new DataColumn(aryline[i], typeof(System.String));
                            mydt.Columns.Add(mydc);
                        }
                        //如果包含标题，则跳过这一行数据
                        if (bhead)
                        {
                            continue;
                        }
                    }

                    mydr = mydt.NewRow();
                    for (int i = 0; i < intColCount; i++)
                    {
                        mydr[i] = aryline[i];
                    }
                    mydt.Rows.Add(mydr);
                }
            }
            return mydt;
        }

        /// <summary>
        /// 解析一行csv数据，返回字符串数组
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private string[] GetCSVLine(string data)
        {
            if (data == null) return null;
            if (data.Length == 0) return new string[0];

            ArrayList result = new ArrayList();

            int pos = -1;
            while (pos < data.Length)
                result.Add(ParseCSVField(data, ref pos));

            return (string[])result.ToArray(typeof(string));
        }

        /// <summary>
        /// 逐个解析一行中的数据项
        /// </summary>
        /// <param name="data"></param>
        /// <param name="startSeparatorPosition"></param>
        /// <returns></returns>
        private string ParseCSVField(string data, ref int startSeparatorPosition)
        {

            if (startSeparatorPosition == data.Length - 1)
            {
                startSeparatorPosition++;
                // 最后一个数据项是空值 
                return "";
            }

            int fromPos = startSeparatorPosition + 1;

            // 处理带引号的数据项
            if (data[fromPos] == '"')
            {
                //如果是引号在最后，则说明数据项只包含引号 
                if (fromPos == data.Length - 1)
                {
                    fromPos++;
                    return "\"";
                }

                // 
                int nextSingleQuote = FindSingleQuote(data, fromPos + 1);
                startSeparatorPosition = nextSingleQuote + 1;
                return data.Substring(fromPos + 1, nextSingleQuote - fromPos - 1).Replace("\"\"", "\"");
            }

            //
            int nextComma = data.IndexOf(',', fromPos);
            if (nextComma == -1)
            {
                startSeparatorPosition = data.Length;
                return data.Substring(fromPos);
            }
            else
            {
                startSeparatorPosition = nextComma;
                return data.Substring(fromPos, nextComma - fromPos);
            }
        }

        /// <summary>
        /// 寻找下一个双引号的位置
        /// </summary>
        /// <param name="data">字符串</param>
        /// <param name="startFrom">其实位置</param>
        /// <returns></returns>
        private int FindSingleQuote(string data, int startFrom)
        {

            int i = startFrom - 1;
            while (++i < data.Length)
                if (data[i] == '"')
                {
                    // 
                    if (i < data.Length - 1 && data[i + 1] == '"')
                    {
                        i++;
                        continue;
                    }
                    else
                        return i;
                }
            // 
            return i;
        }

        /// <summary>
        /// 静默删除文件
        /// </summary>
        /// <param name="strTempFile"></param>
        private void DeleteTempFile(string strTempFile)
        {
            try
            {
                if (File.Exists(strTempFile))
                {
                    File.Delete(strTempFile);
                }
            }
            catch { }
        }

        /// <summary>
        /// 确保目录存在，不存在则创建，除非无法创建则报错
        /// </summary>
        /// <param name="strPath"></param>
        private bool DirectoryExist(string strPath)
        {
            try
            {
                if (!Directory.Exists(strPath))
                {
                    Directory.CreateDirectory(strPath);
                }
                return true;
            }
            catch { return false; }
        }

        #endregion

    }
}
